package korkd.tower;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.camera.hud.HUD;
import org.anddev.andengine.engine.handler.timer.ITimerCallback;
import org.anddev.andengine.engine.handler.timer.TimerHandler;
import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperty;
import org.anddev.andengine.entity.modifier.AlphaModifier;
import org.anddev.andengine.entity.modifier.ColorModifier;
import org.anddev.andengine.entity.modifier.IEntityModifier.IEntityModifierListener;
import org.anddev.andengine.entity.modifier.MoveYModifier;
import org.anddev.andengine.entity.modifier.ParallelEntityModifier;
import org.anddev.andengine.entity.modifier.ScaleModifier;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene.ITouchArea;
import org.anddev.andengine.entity.scene.menu.MenuScene;
import org.anddev.andengine.entity.scene.menu.MenuScene.IOnMenuItemClickListener;
import org.anddev.andengine.entity.scene.menu.animator.DirectMenuAnimator;
import org.anddev.andengine.entity.scene.menu.item.IMenuItem;
import org.anddev.andengine.entity.scene.menu.item.SpriteMenuItem;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.text.ChangeableText;
import org.anddev.andengine.entity.text.Text;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.font.Font;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.util.modifier.IModifier;
import org.anddev.andengine.util.path.ITiledMap;
import org.anddev.andengine.util.path.Path;
import org.anddev.andengine.util.path.astar.AStarPathFinder;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.opengl.GLES20;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.Toast;

class Castle extends Sprite implements IOnMenuItemClickListener
{
	protected static final int MENU_DEPLOY = 0;
	protected static final int MENU_QUIT = MENU_DEPLOY + 1;
	protected static final int MENU_MANAGE_TOWER = MENU_QUIT + 1;
	protected static final int MENU_UPGRADE = MENU_MANAGE_TOWER + 1;

	// Attributes
	private boolean mControlled;
	private int mGoldRate;
	private int mUnitRate;
	private int health;
	private int level;
	
	private MenuScene mMenuScene;
	
	private Player mOwner;
	private Font mGoldFont;
	private ChangeableText mGoldCountText;
	private ParallelEntityModifier mEntityModifier;
	private ArmyPool mArmyPool;
	private HashMap<Castle,Path> mCastlePaths;
	private float mGoldPercentage;
	private float mWoodPercentage;
	private float mStonePercentage;
	private int mSupply;
	private int mSupplyLimit;
	private int mRecruits;
	private ChangeableText mSupplyCountText;
	private ChangeableText mRecruitCountText;
	private TowerDefenseGame mTDG;
	private Map mTowerMap;
	private Path mPath;
	


	
	// Constructor
	public Castle(float pX, float pY, TextureRegion pTextureRegion) {
		super(pX, pY, pTextureRegion);
		this.setControlled(false);
		this.setGoldRate(5);
		this.setUnitRate(2);
		this.setHealth(10);
		this.setLevel(1);
		setCastlePaths(new HashMap<Castle,Path>());
		mRecruits = 0;
		mSupplyLimit = 10;
		mSupply = 0;
		
		//mTowerMap = new Map("tmx/Map.tmx");
		
		//Road r = mTowerMap.getRoad();
		//generatePath(r.end.x,r.end.y,r.start.x,r.start.y);
		
		Random rand = new Random();
		mGoldPercentage = (float)(rand.nextInt(70) + 30) / 100;
		mWoodPercentage = (float)(rand.nextInt(70) + 30) / 100;
		mStonePercentage = (float)(rand.nextInt(70) + 30) / 100;	
		
		// Set the gold text to be off initially and format it
		//mGoldCountText = new ChangeableText(this.getWidth()/2,0, this.mGoldFont, "", 5);
		//mGoldCountText.setText("+"+Integer.toString(this.mGoldRate));
		//mGoldCountText.setVisible(false);
		//this.attachChild(mGoldCountText);
		
		this.registerUpdateHandler(new TimerHandler(5.0f, true, new ITimerCallback() {
			
			@Override
			public void onTimePassed(TimerHandler pTimerHandler) {
				if(mRecruits < 10)
				{
					mRecruits++;
					//mRecruitCountText.setText(Integer.toString(mRecruits));
				}
			}
		}));
	}

	// Methods
	public void levelUp()
	{
		this.level++;
		this.setGoldRate(this.mGoldRate * this.level);
		this.setUnitRate(this.mUnitRate * this.level);
		this.setHealth(this.health + (this.health / 2));
	}
	
	public void TDGame(Player pPlayer)
	{
		if(mTDG == null)
		{
			mTDG = new TowerDefenseGame(this, pPlayer, mPath);
		}
		
		//mTDG.assault();
	}
	
	private void generatePath(int pStartCol, int pStartRow, int pEndCol, int pEndRow)
	{		
		final ITiledMap<TMXLayer> tmap = new ITiledMap<TMXLayer>()
		{
			@Override
			public int getTileColumns() {
				return mTowerMap.getMap().getTileColumns();
			}
			
			@Override
			public int getTileRows()
			{
				return mTowerMap.getMap().getTileRows();
			}
			
			@Override
			public boolean isTileBlocked(TMXLayer pTile, final int pTileColumn, final int pTileRow)
			{
				return false;
			}
			
			@Override
			public float getStepCost(final TMXLayer pTile, final int pFromTileColumn, final int pFromTileRow, final int pToTileColumn, final int pToTileRow)
			{
				TMXProperty cost = mTowerMap.getMap().getTMXLayers().get(0).getTMXTile(pToTileColumn, pToTileRow).getTMXTileProperties(mTowerMap.getMap()).get(0);
				return Float.parseFloat(cost.getValue());
				
			}
			
			@Override
			public void onTileVisitedByPathFinder(int pTileColumn, int pTileRow) {
				// Do Nothing
			}
		};
		
		AStarPathFinder<TMXLayer> AStar = new AStarPathFinder<TMXLayer>(tmap, 200, false);

		mPath = AStar.findPath(this.mTowerMap.getMap().getTMXLayers().get(0), 100000, pStartCol, pStartRow, pEndCol, pEndRow);
		
		if(mPath == null)
		{
			throw new Error("mAPath returned NULL");
		}
	}
	
	@Override
	public boolean onMenuItemClicked(final MenuScene pMenuScene, final IMenuItem pMenuItem, final float pMenuItemLocalX, final float pMenuItemLocalY) {

			switch(pMenuItem.getID()) {
				case MENU_DEPLOY:
					SceneManager.INSTANCE.clearChildScene();
					SceneManager.INSTANCE.enableHUD();
					Toast.makeText(Game.GameContext, "Select a destination", Toast.LENGTH_LONG).show();
					return true;
				case MENU_QUIT:
					/* End Activity. */
					SceneManager.INSTANCE.clearChildScene();
					SceneManager.INSTANCE.enableHUD();
					return true;
				default:
					return false;
			}
	}
	
	@Override
	public boolean onAreaTouched(final TouchEvent pTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY)
	{

		if(pTouchEvent.getAction() == MotionEvent.ACTION_DOWN)
		{
			this.setColor(0.7f, 0.7f, 0.7f, 0.7f);
		}
		if(pTouchEvent.getAction() == MotionEvent.ACTION_UP)
		{
			if(mControlled)
			{
				setControlled(true);
				SceneManager.INSTANCE.disableHUD();
				SceneManager.INSTANCE.setChildScene(mMenuScene);
			}
			else
			{
				setControlled(false);
			}
		}
		return true;
	}
	
	// BEGIN Setters and Getters
	// ****************************************************************
	public void setControlled(boolean controlled, Player Owner) {
		if (controlled == true)
		{
			this.mOwner = Owner;
		}
		else
		{
			this.mOwner = null;
		}
		setControlled(controlled);
	}
	
	
	public void setControlled(boolean controlled) {
		this.mControlled = controlled;
		if (controlled == true)
		{
			this.setColor(0.75f, 0.75f, 1.0f, 1.0f);
		}
		else
		{
			this.setColor(1.0f, 0.75f, 0.75f, 1.0f);
		}
	}

	public boolean isControlled() {
		return mControlled;
	}

	public void setGoldRate(int goldRate) {
		this.mGoldRate = goldRate;
	}

	public int getGoldRate() {
		return mGoldRate;
	}

	public void setUnitRate(int unitRate) {
		this.mUnitRate = unitRate;
	}

	public int getUnitRate() {
		return mUnitRate;
	}

	public void setHealth(int health) {
		this.health = health;
	}

	public int getHealth() {
		return health;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public int getLevel() {
		return level;
	}

	public void setMenuScene(MenuScene pMenuScene) {
		mMenuScene = pMenuScene;
	}

	public HashMap<Castle,Path> getCastlePaths() {
		return mCastlePaths;
	}

	public void setCastlePaths(HashMap<Castle, Path> hashMap) {
		this.mCastlePaths = hashMap;
	}

	public Path getPath(Castle mDestCastle) {
		return mCastlePaths.get(mDestCastle);
	}
	
	// END Setters and Getters
	// ****************************************************************
}